home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 85 / CD Temático 40 Febrero 2004.iso / DOS / ntfs / user / ntcp.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-15  |  6.5 KB  |  348 lines

  1. /*
  2.  *  ntcp.c
  3.  *
  4.  *  Copyright (C) 1995 Martin von L÷wis
  5.  *  Copyright (C) 1997 RΘgis Duchesne
  6.  */
  7.  
  8. #ifdef HAVE_CONFIG_H
  9. #include "config.h"
  10. #endif
  11.  
  12. #include <stdio.h>
  13. #include <errno.h>
  14. #ifdef HAVE_FCNTL_H
  15. #include <fcntl.h>
  16. #endif
  17. #ifdef HAVE_GETOPT_H
  18. #include <getopt.h>
  19. #else
  20. #define getopt_long(a,v,o,ol,x)        getopt(a,v,o)
  21. #endif
  22. #ifdef HAVE_UNISTD_H
  23. #include <unistd.h>
  24. #endif
  25. #ifdef HAVE_IO_H
  26. #include <io.h>
  27. #endif
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <limits.h>
  31. #include "ntfstypes.h"
  32. #include "struct.h"
  33. #include "util.h"
  34. #include "nttools.h"
  35. #include "inode.h"
  36.  
  37. char *short_opts="Vh";
  38. #ifdef HAVE_GETOPT_H
  39. struct option options[]={
  40.     {"version",0,0,'V'},
  41.     {"help",0,0,'h'},
  42.     {0,0,0,0}
  43. };
  44. #endif
  45.  
  46. unsigned int type=ngt_nt;
  47. unsigned int charset=nct_utf8;
  48.  
  49.  
  50. void usage(void)
  51. {
  52.   fprintf(stderr,"ntcp [-V|h] <src> <dst>\n"
  53.       "Files on the NTFS volume are accessed as //<device>/<path>\n");
  54. }
  55.  
  56. struct ntfs_file{
  57.   ntfs_inode ino;
  58.   ntfs_attribute *data;
  59.   ntfs_offset_t offset;
  60. };
  61.  
  62. void
  63. write_unix(void *file,void *buf,size_t len)
  64. {
  65.   if(write(*(int*)file,buf,len)!=len){
  66.     perror("cp2unix");
  67.     exit(1);
  68.   }
  69. }
  70.  
  71. int
  72. read_unix(void *file,void *buf,size_t len)
  73. {
  74.   int result;
  75.   result=read(*(int*)file,buf,len);
  76.   if(result==-1){
  77.     perror("read_unix");
  78.     exit(1);
  79.   }
  80.   return result;
  81. }
  82.  
  83. int
  84. close_unix(void *file)
  85. {       /* When close is Ok, errno isn't set to zero in some implementation */
  86.     if(close(*(int*)file)==0)
  87.       return 0;
  88.     else
  89.       return errno;
  90. }
  91.  
  92. void
  93. write_nt(void *file,void* buf,size_t len)
  94. {
  95.   struct ntfs_file* f=file;
  96.   struct ntfs_io io;
  97.   int error;
  98.   io.fn_get=ntfs_get;
  99.   io.param=buf;
  100.   io.size=len;
  101.   io.do_read=0;
  102.   error=ntfs_readwrite_attr(&f->ino,f->data,f->offset,&io);
  103.   if(error){
  104.     fprintf(stderr,"Error %d writing to ntfs\n",error);
  105.     exit(1);
  106.   }
  107.   f->offset+=len;
  108. }
  109.  
  110. int
  111. read_nt(void *file,void *buf,size_t len)
  112. {
  113.   struct ntfs_file* f=file;
  114.   struct ntfs_io io;
  115.   int error;
  116.   io.fn_put=ntfs_put;
  117.   io.param=buf;
  118.   io.size=len;
  119.   io.do_read=1;
  120.   error=ntfs_readwrite_attr(&f->ino,f->data,f->offset,&io);
  121.   if(error){
  122.     fprintf(stderr,"Error %d reading from ntfs\n",error);
  123.     exit(1);
  124.   }
  125.   f->offset+=io.size;
  126.   return io.size;
  127. }
  128.  
  129. int 
  130. close_nt(void *file)
  131. {
  132.     return ntfs_update_inode(file);
  133. }
  134.  
  135. typedef struct _methods
  136. {
  137.     void (*write_func)(void*,void*,size_t);
  138.     int (*read_func)(void*,void*,size_t);
  139.     int (*close_func)(void*);
  140. } *methods;
  141.  
  142. struct _methods m_unix =
  143. {
  144.     write_unix,
  145.     read_unix,
  146.     close_unix
  147. };
  148.  
  149. struct _methods m_nt =
  150. {
  151.     write_nt,
  152.     read_nt,
  153.     close_nt
  154. };
  155.  
  156. void copy(methods r,void *rf,methods w,void *wf)
  157. {
  158.   void *buf=malloc(8192);
  159.   int len;
  160.   int error;
  161.   
  162.   do{
  163.     len=r->read_func(rf,buf,8192);
  164.     w->write_func(wf,buf,len);
  165.   }while(len==8192);
  166.   error = w->close_func(wf);
  167.   if(error)
  168.       fprintf(stderr,"When closing w:%s\n", strerror(error));
  169.   error = r->close_func(rf);
  170.   if(error)
  171.       fprintf(stderr,"When closing r:%s\n", strerror(error));
  172. }
  173.  
  174. int
  175. ntfs_creat (ntfs_inode *dir, ntfs_inode *ino, char* name)
  176. {
  177.     int error;
  178.     
  179.     error=ntfs_alloc_file(dir,ino,name,strlen(name));
  180.     if(error)
  181.         return error;
  182.     error=ntfs_update_inode(ino);
  183.     if(error)
  184.         return error;
  185.     error=ntfs_update_inode(dir);
  186.     return error;
  187. }
  188.  
  189. int 
  190. ntfs_open(char *name,methods m,void **f,int flags)
  191. {
  192.     ntfs_volume *vol;
  193.     char device[256];
  194.     char *it;
  195.     int inum;
  196.     struct ntfs_file *file;
  197.     int error;
  198.  
  199.     for(it=name+2;*it && *it!='/';it++)
  200.         /*nothing*/;
  201.     if(it!=name+2)
  202.     {
  203.       strcpy(device,"/dev/");
  204.       strncpy(device+5,name+2,(it-name)-2);
  205.       device[(it-name)+3]='\0';
  206.     }
  207.     vol=ntfs_open_volume(device,0,1,0);
  208.     if(!vol)return ENODEV;
  209.     vol->ngt=type;
  210.     vol->nct=charset;
  211.  
  212.     file=malloc(sizeof(struct ntfs_file));
  213.     inum=5;
  214.     /* walk the directory tree */
  215.     name=it;
  216.     if(*name=='/')name++;
  217.     do{
  218.         char *next;
  219.         if(ntfs_init_inode(&file->ino,vol,inum)){
  220.             fprintf(stderr,"error finding %s\n",it);
  221.             return EIO;
  222.         }
  223.         if(!name || !*name)break;
  224.         next=strpbrk(name,NTFS_PATH_SEP);
  225.         if(next){
  226.             *next='\0';
  227.             next++;
  228.         }
  229.         inum=ntfs_find_file(&file->ino,name);
  230.         if(inum==-1){
  231.             ntfs_inode new_ino;
  232.             if(next)
  233.                 return ENOENT;
  234.             error = ntfs_creat(&file->ino, &new_ino, name);
  235.             if(error)
  236.                 return error;
  237.             file->ino = new_ino;
  238.             break;
  239.         }
  240.         name=next;
  241.     }while(1);
  242.     file->data=ntfs_find_attr(&file->ino,vol->at_data,0);
  243.     if(!file->data)
  244.         return EISDIR;
  245.     *m = m_nt;
  246.     *f = file;
  247.     return 0;
  248. }
  249.  
  250. int
  251. unix_open(char *name,methods m,void **f,int flags)
  252. {
  253.     int *file=malloc(sizeof(int));
  254.     *file=open(name,flags,0777);
  255.     if(*file==-1)return errno;
  256.     *m = m_unix;
  257.     *f=file;
  258.     return 0;
  259. }
  260.  
  261. int
  262. do_open(char *name,methods m,void **f,int flags)
  263. {
  264.     int error;
  265.     if(name[0]=='/' && name[1]=='/')
  266.         error=ntfs_open(name,m,f,flags);
  267.     else
  268.         error=unix_open(name,m,f,flags);
  269.  
  270.     if(error == EISDIR && (flags & O_CREAT))
  271.         return error;
  272.     
  273.     if(error){
  274.         fprintf(stderr,"%s:%s\n",name,strerror(error));
  275.         exit(1);
  276.     }
  277.     return 0;
  278. }
  279.  
  280. void
  281. join(char* dir, char* file)
  282. {
  283.     char *next;
  284.     for(next = strpbrk(dir,NTFS_PATH_SEP);next; 
  285.         next = strpbrk(next,NTFS_PATH_SEP))
  286.         dir=next=next+1;
  287.     if(*dir != '\0')
  288.     {
  289.         dir += strlen(dir);
  290.         *dir = '/';
  291.         dir++;
  292.     }
  293.     for(next = strpbrk(file, NTFS_PATH_SEP); next; 
  294.         next = strpbrk(next, NTFS_PATH_SEP))
  295.         file = next = next+1;
  296.     strcpy(dir,file);
  297. }
  298.  
  299. int main(int argc,char *argv[])
  300. {
  301.     int c;
  302.     extern int opterr,optind;
  303.     extern char* optarg;
  304.     struct _methods m1,m2;
  305.     void *f1,*f2;
  306.  
  307.     opterr=1;
  308.     while((c=getopt_long(argc,argv,short_opts,options,NULL))>0)
  309.         switch(c)
  310.         {
  311.         case 'V': printf("ntcp" NTFS_VERSION "\n");exit(0);break;
  312.         case 'h': usage();exit(0);break;
  313.         }
  314.     if(optind+2!=argc){
  315.         usage();
  316.         exit(1);
  317.     }
  318. #ifdef MSDOS
  319.     do_open(argv[optind], &m1, &f1, O_RDONLY|O_BINARY);
  320.     if(do_open(argv[optind+1], &m2, &f2, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY) == EISDIR)
  321. #else
  322.     do_open(argv[optind], &m1, &f1, O_RDONLY);
  323.     if(do_open(argv[optind+1], &m2, &f2, O_WRONLY|O_CREAT) == EISDIR)
  324. #endif
  325.     {
  326.         char newname[NAME_MAX];
  327.         strcpy(newname, argv[optind+1]);
  328.         join(newname,argv[optind]);
  329. #ifdef MSDOS
  330.         if(do_open(newname, &m2, &f2, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY) == EISDIR)
  331. #else
  332.         if(do_open(newname, &m2, &f2, O_WRONLY|O_CREAT) == EISDIR)
  333. #endif
  334.         {
  335.             fprintf(stderr,"%s:%s\n",newname,strerror(EISDIR));
  336.             exit(1);
  337.         }
  338.     }
  339.     copy(&m1,f1,&m2,f2);
  340.     return 0;
  341. }
  342.  
  343. /*
  344.  * Local variables:
  345.  * c-file-style: "linux"
  346.  * End:
  347.  */
  348.